【js】ES Stage/TS 5.2中的新特性useing关键字
Jul 2, 2023笔记jses【js】ES Stage/TS 5.2 中的新特性 useing 关键字
using
关键字是 tc39 提案ECMAScript Explicit Resource Management提出的,用于为各种资源(内存、I/O 等)提供统一的生命周期管理(何时分配、何时释放等)。
目前(2023.07.02
)状态:
- TS
v5.2
率先引入了这个关键字,目前还是在 dev 版本、未成为正式版。 - ECMAScript Stage:
3
(“候选(candidate)”) - Last Presented:
March, 2023
介绍
using
关键字作用是:当离开作用域时,你可以使用 Symbol.dispose
释放掉任何内容。
语法
using
:
1 | // a synchronously-disposed, block-scoped resource |
结合await
关键字:
1 | // an asynchronously-disposed, block-scoped resource |
await using
可以出现在以下上下文中:
- 模块的顶层任何允许使用 VariableStatement(变量声明) 的地方,只要它不是立即嵌套在 CaseClause 或 DefaultClause 中即可。
- 在异步函数或异步生成器的主体中任何允许使用 VariableStatement 的地方,只要它不立即嵌套在 CaseClause 或 DefaultClause 中即可。
在
for-of
或for-await-of
语句的头部。如1
2
3
4
5
6
7
8
9
10
11
12
13for (await using x of y) ...
for await (await using x of y) ...
// sync iteration, sync disposal
for (using x of y) ; // no implicit `await` at end of each iteration
// sync iteration, async disposal
for (await using x of y) ; // implicit `await` at end of each iteration
// async iteration, sync disposal
for await (using x of y) ; // implicit `await` at end of each iteration
// async iteration, async disposal
for await (await using x of y) ; // implicit `await` at end of each iteration
Symbol.dispose
Symbol.dispose
是 JavaScript 中的一个新的全局符号。任何带有 Symbol.dispose
功能的都被视为“资源”—— “具有特定生命周期的对象” ——并且可以与关键字 using
一起使用。
ecma262-compare: A method that performs explicit resource cleanup on an object. Called by the semantics of the using declaration and DisposableStack objects.
1 | const resource = { |
await using
使用 Symbol.asyncDispose
和 await using
来处理需要异步处理的资源。
1 | const getResource = () => ({ |
在代码继续执行之前 js 引擎将等待 Symbol.asyncDispose
函数。这对于数据库连接等资源很有用,例如您希望在这些资源中确保连接在程序继续运行之前关闭。
using
和await using
的基本区别
主要在Symbol.dispose
和Symbol.asyncDispose
定义上
句法 | 迭代器 | 处理器 |
---|---|---|
for (using x of y) |
@@iterator |
@@dispose |
for (await using x of y) |
@@iterator |
@@asyncDispose/@@dispose |
for await (using x of y) |
@@asyncIterator/@@iterator |
@@dispose |
for await (await using x of y) |
@@asyncIterator/@@iterator |
@@asyncDispose/@@dispose |
如:
1 | const res = { [Symbol.dispose]() {} }; |
使用
使用场景很多
文件处理
没有 using
:
1 | import { open } from 'node:fs/promises'; |
使用 using
:
1 | import { open } from "node:fs/promises"; |
数据库连接
使用
using
管理数据库连接是 C# 中的一个常见用例,可见文档using 语句 - 确保正确使用可释放对象。Golang 中的defer
函数也有点这个意味。
没有 using
:
1 | const connection = await getDb(); |
使用 using
:
1 | const getConnection = async () => { |
实现机制
从目前`typescript@5.2.0-beta`版(https://www.npmjs.com/package/typescript/v/5.2.0-beta)来看
原代码:
1 | { |
tsc 编译后:
1 | { |
using
关键字没有处理,看来有可能是无法 polyfill 的语法。最终成为标准后会是如何待后续跟进。
Author
My name is Micheal Wayne and this is my blog.
I am a front-end software engineer.
Contact: michealwayne@163.com